import IconFont from '@/IconFontAl';
import defPic from '@/assets/imgs/default_head.png';
import { Checkbox, Empty, Radio, Skeleton } from 'antd';
import type { CheckboxChangeEvent } from 'antd/es/checkbox';
import classNames from 'classnames';
import {
  forwardRef,
  useImperativeHandle,
  useLayoutEffect,
  useMemo,
  useState,
} from 'react';
import CrumbList from './CrumbList';
import {
  ChoiceListRef,
  CrumbItem,
  IPositionDetail,
  PosChoiceListProps,
  TChoiceStaffValue,
  TPosition,
  TPositionGroupItem,
  posRequestParams,
} from './interface';

import { getOtherCheckboxStaObj } from './utils';

const PosChoiceList = forwardRef<ChoiceListRef, PosChoiceListProps>(
  (props, ref) => {
    const {
      defaultValue,
      onPosChoiceChange,
      onPosChoiceChangeBatch,
      posRequest,
      requestParams,
      keyWord,
      prefixCls,
      onlyChoicePeople,
      choiceBtn,
    } = props;
    const { entId, entName } = requestParams;
    const [selectedValues, setSelectedValues] = useState<TChoiceStaffValue[]>(
      defaultValue || [],
    );
    const [loading, showLoading] = useState<boolean>(false);
    //面包屑
    const [crumbList, setCrumbList] = useState<CrumbItem[]>([
      { entId, name: entName, guid: entId },
    ]);

    // 定义列表数据
    const [posGroupList, setPosGroupList] = useState<
      IPositionDetail['positionGroupList']
    >([]);
    const [posStaffList, setPosStaffList] = useState<IPositionDetail['plist']>(
      [],
    );

    const getPosList = (params: posRequestParams) => {
      showLoading(true);
      return posRequest(params)
        .then((resData) => {
          //resData.positionGroupList 和resData.plist不会同时存在(岗位组子级只能是岗位，不可能是人)
          // console.log('--PosChoiceList--resData--:', resData);
          const { positionGroupList, plist } = resData || {};
          setPosGroupList(positionGroupList || []);
          const currPosOrEntdId = params.positionId || params.entId;
          positionGroupList?.forEach((groupItem) => {
            groupItem.plist?.forEach((pItem) => {
              pItem.combineId = `${currPosOrEntdId}_${pItem.guid}`;
            });
          });

          // 注：如果同一个人有不同岗位，采用combineId = positionId + roleId 标记唯一性,crumbList[0].guid === entId; 但是crumbList.length === 1时，只能选岗位组下的岗位
          const tempPlist = (plist || []).map((pItem) => ({
            ...pItem,
            combineId: `${params.positionId}_${pItem.personId}`,
          }));
          setPosStaffList(tempPlist);
        })
        .finally(() => {
          showLoading(false);
        });
    };

    //搜索
    const handleSearch = (keyWord: string | undefined) => {
      const positionId = crumbList[crumbList.length - 1].entId
        ? undefined
        : crumbList[crumbList.length - 1].guid;
      getPosList({ entId, positionId, keyWord });
    };

    //删除选中
    const handleDelete = (selectedItem: TChoiceStaffValue) => {
      const tempSelectedValues = selectedValues;
      const exitIndex = tempSelectedValues.findIndex((valItem) =>
        selectedItem.combineId
          ? valItem.combineId === selectedItem.combineId
          : valItem.guid === selectedItem.guid,
      );
      if (exitIndex > -1) {
        tempSelectedValues.splice(exitIndex, 1);
        onPosChoiceChange('delete', selectedItem);
        setSelectedValues([...tempSelectedValues]);
      }
    };

    useImperativeHandle(ref, () => ({
      search: handleSearch,
      delete: handleDelete,
      resetSelectedValues: (newSelValues: TChoiceStaffValue[]) => {
        setSelectedValues(newSelValues);
      },
    }));

    useLayoutEffect(() => {
      getPosList({ entId });
    }, []);

    //面包屑
    const handleCrumbClick = (currCurmb: CrumbItem) => {
      // console.log('--currCurmb--:', currCurmb);
      const { guid, entId: crumbEntId } = currCurmb;
      const currIndex = crumbList.findIndex(
        (crumbItem) => crumbItem.guid === guid,
      );
      if (currIndex > -1) {
        crumbList.splice(currIndex + 1);
        setCrumbList([...crumbList]);
        getPosList({
          entId,
          positionId: crumbEntId ? undefined : guid,
          keyWord,
        });
      }
    };

    //下一级
    const handPosChild = (e: React.MouseEvent, roleItem: TPosition) => {
      e.stopPropagation();
      const { guid, name } = roleItem;
      getPosList({ entId, positionId: guid, keyWord }).then(() => {
        crumbList.push({ guid, name });
        setCrumbList(crumbList);
      });
    };

    //全选
    const handleAllChoiceChange = (e: CheckboxChangeEvent) => {
      // setChoiceAll(e.target.checked);
      const allChecked = e.target.checked;
      const tempOperationList: TChoiceStaffValue[] = [];
      const tempSelectedValues = selectedValues;
      if (!onlyChoicePeople) {
        const posList = posGroupList!.reduce(
          (
            prev: TPosition[],
            curr: TPositionGroupItem,
            index: number,
            array: IPositionDetail['positionGroupList'],
          ) => {
            const tempTList = curr.plist || [];
            prev = [...prev, ...tempTList];
            return prev;
          },
          [],
        );

        posList.forEach((posItem) => {
          const existPosItemIndex = tempSelectedValues.findIndex(
            (selItem) => selItem.combineId === posItem.combineId,
          );
          const tempSelItem: TChoiceStaffValue = {
            choiceType: 'pos',
            guid: posItem.guid,
            name: posItem.name,
            combineId: posItem.combineId,
          };
          if (existPosItemIndex < 0 && allChecked) {
            //选中不存在
            tempSelectedValues.push(tempSelItem);
            tempOperationList.push(tempSelItem);
          }
          if (existPosItemIndex > -1 && !allChecked) {
            //取消选中已存在
            tempSelectedValues.splice(existPosItemIndex, 1);
            tempOperationList.push(tempSelItem);
          }
        });
      }
      posStaffList!.forEach((posStaffItem) => {
        const existPosStaffItemIndex = selectedValues.findIndex(
          (selItem) => selItem.combineId === posStaffItem.combineId,
        );
        const tempSelItem: TChoiceStaffValue = {
          choiceType: 'pos',
          ...posStaffItem,
        };
        if (existPosStaffItemIndex < 0 && allChecked) {
          tempSelectedValues.push(tempSelItem);
          tempOperationList.push(tempSelItem);
        }
        if (existPosStaffItemIndex > -1 && !allChecked) {
          tempSelectedValues.splice(existPosStaffItemIndex, 1);
          tempOperationList.push(tempSelItem);
        }
      });

      onPosChoiceChangeBatch(allChecked ? 'add' : 'delete', tempOperationList);
      setSelectedValues([...tempSelectedValues]);
    };

    //当前行选中、取消选中
    const choiceItem = (
      type: 'guid' | 'personId',
      item: any, //Partial<TPosition & TPerson>,
    ) => {
      if (type === 'guid' && onlyChoicePeople) return;
      let tempSelectedValues = selectedValues;
      const exitIndex = tempSelectedValues.findIndex(
        (valItem) => valItem.combineId === item.combineId,
      );
      const tempValItem: TChoiceStaffValue =
        type === 'guid'
          ? {
              choiceType: 'pos',
              guid: item.guid,
              name: item.name,
              combineId: item.combineId,
            }
          : { choiceType: 'pos', ...item };
      if (exitIndex < 0) {
        if (choiceBtn === 'checkbox') {
          tempSelectedValues.push(tempValItem);
        } else {
          tempSelectedValues = [tempValItem];
        }
      } else {
        tempSelectedValues.splice(exitIndex, 1);
      }
      onPosChoiceChange(exitIndex < 0 ? 'add' : 'delete', tempValItem);
      setSelectedValues([...tempSelectedValues]);
    };

    //全选checkbox是否显示
    const allCheckBoxShow = useMemo(() => {
      let tempShow = false;
      if (choiceBtn === 'checkbox') {
        if (onlyChoicePeople) {
          if (posStaffList!.length > 0) {
            tempShow = true;
          }
        } else {
          if (posGroupList!.length > 0 || posStaffList!.length > 0) {
            tempShow = true;
          }
        }
      }
      return tempShow;
    }, [onlyChoicePeople, choiceBtn, posGroupList, posStaffList]);

    return (
      <div className={`${prefixCls}-choice`}>
        <CrumbList
          crumbList={crumbList}
          onCrumbClick={handleCrumbClick}
          prefixCls={prefixCls}
        />
        {allCheckBoxShow && (
          <Checkbox
            onChange={handleAllChoiceChange}
            indeterminate={
              getOtherCheckboxStaObj(
                'pos',
                selectedValues,
                posGroupList,
                posStaffList || [],
                onlyChoicePeople,
              ).indeterminate
            }
            checked={
              getOtherCheckboxStaObj(
                'pos',
                selectedValues,
                posGroupList,
                posStaffList || [],
                onlyChoicePeople,
              ).checked
            }
            style={{ marginLeft: '5px' }}
          >
            全选
          </Checkbox>
        )}
        <ul className="choice_list">
          <Skeleton
            loading={loading}
            active
            paragraph={{ rows: 4, width: 296 }}
            title={false}
          >
            {posGroupList?.map((groupItem) => (
              <li className="list_group_item" key={groupItem.groupId}>
                <div className="group_item_name">
                  <IconFont type="icon-gang_wei" className="name_icon" />
                  <p className="name_text">{groupItem.name}</p>
                </div>
                <ul className="group_item_child">
                  {groupItem.plist?.map((posItem) => (
                    <li
                      key={posItem.combineId}
                      className="list_other_item"
                      onClick={() => {
                        choiceItem('guid', posItem);
                      }}
                    >
                      {choiceBtn === 'checkbox' && !onlyChoicePeople && (
                        <Checkbox
                          checked={
                            selectedValues.findIndex(
                              (valItem) => valItem.guid === posItem.guid,
                            ) > -1
                              ? true
                              : false
                          }
                          style={{ marginLeft: '5px' }}
                        />
                      )}

                      {choiceBtn === 'radio' && !onlyChoicePeople && (
                        <Radio
                          checked={
                            selectedValues.findIndex(
                              (valItem) => valItem.guid === posItem.guid,
                            ) > -1
                              ? true
                              : false
                          }
                          style={{ marginLeft: '5px', marginInlineEnd: '0px' }}
                        />
                      )}
                      <div
                        className="item_center"
                        style={{ marginLeft: onlyChoicePeople ? '5px' : '0px' }}
                      >
                        <p className="center_text">{posItem.name}</p>
                      </div>
                      <p
                        className={classNames('item_right', {
                          ['disabled']:
                            !posItem.peopleNumber ||
                            selectedValues.findIndex(
                              (valItem) => valItem.guid === posItem.guid,
                            ) > -1,
                        })}
                        onClick={(e) => {
                          posItem.peopleNumber &&
                            selectedValues.findIndex(
                              (valItem) => valItem.guid === posItem.guid,
                            ) < 0 &&
                            handPosChild(e, posItem);
                        }}
                      >
                        下级
                      </p>
                    </li>
                  ))}
                </ul>
              </li>
            ))}
            {posStaffList?.map((posStaffItem) => (
              <li
                key={posStaffItem.combineId}
                className="list_staff_item"
                onClick={() => {
                  choiceItem('personId', posStaffItem);
                }}
              >
                {choiceBtn === 'checkbox' ? (
                  <Checkbox
                    checked={
                      selectedValues.findIndex(
                        (valItem) =>
                          valItem.combineId === posStaffItem.combineId,
                      ) > -1
                        ? true
                        : false
                    }
                    style={{ marginLeft: '5px' }}
                  />
                ) : (
                  <Radio
                    checked={
                      selectedValues.findIndex(
                        (valItem) =>
                          valItem.combineId === posStaffItem.combineId,
                      ) > -1
                        ? true
                        : false
                    }
                    style={{ marginLeft: '5px', marginInlineEnd: '0px' }}
                  />
                )}
                <div className="item_person">
                  <img
                    className="person_avatar"
                    src={posStaffItem.hdpic || defPic}
                    alt="头像"
                  />
                  <p className="person_text">
                    <span>{posStaffItem.personName}</span>
                    <span>({posStaffItem.phone})</span>
                  </p>
                </div>
              </li>
            ))}
            {!loading &&
              posGroupList!.length <= 0 &&
              posStaffList!.length <= 0 && (
                <Empty
                  image={Empty.PRESENTED_IMAGE_SIMPLE}
                  description={false}
                />
              )}
          </Skeleton>
        </ul>
      </div>
    );
  },
);

export default PosChoiceList;
